Unity初级案例

您所在的位置:网站首页 吃豆人规则 原版 Unity初级案例

Unity初级案例

2023-07-03 08:21| 来源: 网络整理| 查看: 265

1.用代码控制动画状态机及设置渲染顺序

//获取移动方向 Vector2 dir = dest - (Vector2)transform.position; //把获取到的移动方向设置给动画状态机 anim.SetFloat("DirX", dir.x); anim.SetFloat("DirY", dir.y);

2.为迷宫加入可以被吃掉的豆点

创建豆点Pacdot,添加碰撞体,并且添加Pacdot脚本

using System.Collections; using System.Collections.Generic; using UnityEngine; public class Pacdot : MonoBehaviour { private void OnTriggerEnter2D(Collider2D collision) { if(collision.gameObject.name == "Pacman") { Destroy(gameObject); } } }

运行程序,结果如下

3.创建四个敌人并采用重写状态机控制动画

4.用现有的知识模拟AI的思路讲解

使用A*寻路和感知系统来完成鬼的寻路。

5.让鬼可以按照单条路径巡逻

首先添加路径点

然后给鬼添加GhostMove脚本,让它移动

using System.Collections; using System.Collections.Generic; using UnityEngine; public class GhostMove : MonoBehaviour { //储存所有路径点的Transform组件 public Transform[] wayPoints; public float speed = 0.2f; //当前在前往哪个路径点的途中 private int index = 0; private Animator anim; private void Awake() { anim = GetComponent(); } private void FixedUpdate() { if (transform.position != wayPoints[index].position) { Vector2 temp = Vector2.MoveTowards(transform.position, wayPoints[index].position, speed); GetComponent().MovePosition(temp); } else { index = (index + 1) % wayPoints.Length; } Vector2 dir = (Vector2)wayPoints[index].position - (Vector2)transform.position; anim.SetFloat("DirX", dir.x); anim.SetFloat("DirY", dir.y); } private void OnTriggerEnter2D(Collider2D collision) { if (collision.gameObject.name == "Pacman") { Destroy(collision.gameObject); } } }

运行程序,结果如下

6.改进巡逻系统使鬼可以随机选择一条路径巡逻

重新编写巡逻系统

using System.Collections; using System.Collections.Generic; using UnityEngine; public class GhostMove : MonoBehaviour { public GameObject[] wayPointsGos; public float speed = 0.2f; //当前在前往哪个路径点的途中 private int index = 0; private Animator anim; private List wayPoints = new List(); private void Awake() { anim = GetComponent(); } private void Start() { LoadAPath(wayPointsGos[Random.Range(0, 2)]); } private void FixedUpdate() { if (transform.position != wayPoints[index]) { Vector2 temp = Vector2.MoveTowards(transform.position, wayPoints[index], speed); GetComponent().MovePosition(temp); } else { index++; if(index >= wayPoints.Count) { index = 0; LoadAPath(wayPointsGos[Random.Range(0, 2)]); } } Vector2 dir = (Vector2)wayPoints[index] - (Vector2)transform.position; anim.SetFloat("DirX", dir.x); anim.SetFloat("DirY", dir.y); } private void OnTriggerEnter2D(Collider2D collision) { if (collision.gameObject.name == "Pacman") { Destroy(collision.gameObject); } } private void LoadAPath(GameObject go) { wayPoints.Clear(); foreach (Transform t in go.transform) { wayPoints.Add(t.position); } } }

运行程序结果如下

7.完善用巡逻来模拟AI的逻辑

添加GameManager脚本,让鬼的初始路径各不相同

using System.Collections; using System.Collections.Generic; using UnityEngine; public class GhostMove : MonoBehaviour { public GameObject[] wayPointsGos; public float speed = 0.2f; //当前在前往哪个路径点的途中 private int index = 0; private Animator anim; private List wayPoints = new List(); private Vector3 startPos; private void Awake() { anim = GetComponent(); } private void Start() { startPos = transform.position + new Vector3(0, 3, 0); //初始化路径 LoadAPath(wayPointsGos[GameManager._instance.usingIndex[GetComponent().sortingOrder - 2]]); } private void FixedUpdate() { if (transform.position != wayPoints[index]) { Vector2 temp = Vector2.MoveTowards(transform.position, wayPoints[index], speed); GetComponent().MovePosition(temp); } else { index++; if(index >= wayPoints.Count) { index = 0; LoadAPath(wayPointsGos[Random.Range(0, wayPointsGos.Length)]); } } Vector2 dir = (Vector2)wayPoints[index] - (Vector2)transform.position; anim.SetFloat("DirX", dir.x); anim.SetFloat("DirY", dir.y); } private void OnTriggerEnter2D(Collider2D collision) { if (collision.gameObject.name == "Pacman") { Destroy(collision.gameObject); } } private void LoadAPath(GameObject go) { wayPoints.Clear(); foreach (Transform t in go.transform) { wayPoints.Add(t.position); } wayPoints.Insert(0, startPos); wayPoints.Add(startPos); } }

然后在GhostMove中初始化路径

//初始化路径 LoadAPath(wayPointsGos[GameManager._instance.usingIndex[GetComponent().sortingOrder - 2]]);

运行程序结果如下

8.引入超级豆点奖励道具

在GameManager中添加生成超级豆点的代码

private void CreateSuperPacdot() { int tempIndex = Random.Range(0, pacdotGos.Count); pacdotGos[tempIndex].transform.localScale = new Vector3(3, 3, 3); pacdotGos[tempIndex].GetComponent().isSuperPacdot = true; }

在Pacdot中添加吃豆人碰到超级豆点的方法

private void OnTriggerEnter2D(Collider2D collision) { if(collision.gameObject.name == "Pacman") { if (isSuperPacdot) { //TODO //告诉GameManager我是超级豆子而且还被吃了 //让吃豆人变成超级吃豆人,可以吃鬼 } Destroy(gameObject); } }

在GhostMove中添加吃了超级豆点的吃豆人碰到鬼的方法

private void OnTriggerEnter2D(Collider2D collision) { if (collision.gameObject.name == "Pacman") { if (GameManager._instance.isSuperPacman) { //TODO //真倒霉,碰到了超级吃豆人,我要回家躲躲 } Destroy(collision.gameObject); } }

9.完善超级豆点的功能

在GameManager中添加有关超级豆的一些代码

private void Start() { Invoke("CreateSuperPacdot", 10f); } public void OnEatPacdot(GameObject go) { pacdotGos.Remove(go); } public void OnEatSuperPacdot() { Invoke("CreateSuperPacdot", 10f); isSuperPacman = true; FreezeEnemy(); StartCoroutine("RecoverEnemy"); } IEnumerator RecoverEnemy() { yield return new WaitForSeconds(3f); DisFreezeEnemy(); isSuperPacman = false; } private void CreateSuperPacdot() { int tempIndex = Random.Range(0, pacdotGos.Count); pacdotGos[tempIndex].transform.localScale = new Vector3(3, 3, 3); pacdotGos[tempIndex].GetComponent().isSuperPacdot = true; } private void FreezeEnemy() { binky.GetComponent().enabled = false; clyde.GetComponent().enabled = false; inky.GetComponent().enabled = false; pinky.GetComponent().enabled = false; binky.GetComponent().color = new Color(0.7f, 0.7f, 0.7f, 0.7f); clyde.GetComponent().color = new Color(0.7f, 0.7f, 0.7f, 0.7f); inky.GetComponent().color = new Color(0.7f, 0.7f, 0.7f, 0.7f); pinky.GetComponent().color = new Color(0.7f, 0.7f, 0.7f, 0.7f); } private void DisFreezeEnemy() { binky.GetComponent().enabled = true; clyde.GetComponent().enabled = true; inky.GetComponent().enabled = true; pinky.GetComponent().enabled = true; binky.GetComponent().color = new Color(1, 1, 1, 1); clyde.GetComponent().color = new Color(1, 1, 1, 1); inky.GetComponent().color = new Color(1, 1, 1, 1); pinky.GetComponent().color = new Color(1, 1, 1, 1); }

在 Pacdot中修改碰撞代码

private void OnTriggerEnter2D(Collider2D collision) { if(collision.gameObject.name == "Pacman") { if (isSuperPacdot) { GameManager._instance.OnEatPacdot(gameObject); GameManager._instance.OnEatSuperPacdot(); Destroy(gameObject); } else { GameManager._instance.OnEatPacdot(gameObject); Destroy(gameObject); } } }

在 GhostMove中修改碰撞代码

private void OnTriggerEnter2D(Collider2D collision) { if (collision.gameObject.name == "Pacman") { if (GameManager._instance.isSuperPacman) { transform.position = startPos - new Vector3(0, 3, 0); index = 0; } else { Destroy(collision.gameObject); } } }

运行程序,结果如下 

10.设计UI界面

11.处理准备时的倒计时动画

在GameManager中添加游戏逻辑处理

public GameObject startpanel; public GameObject gamePanel; public GameObject startCountDonwPrefab; public GameObject gameoverPrefab; public GameObject winPrefab; public AudioClip startClip; private void Start() { SetGameState(false); } public void OnStartButton() { StartCoroutine(PlayerStartCountDown()); AudioSource.PlayClipAtPoint(startClip, Vector3.zero); startpanel.SetActive(false); } public void OnExitButton() { Application.Quit(); } IEnumerator PlayerStartCountDown() { GameObject go = Instantiate(startCountDonwPrefab); yield return new WaitForSeconds(4f); Destroy(go); SetGameState(true); Invoke("CreateSuperPacdot", 10f); gamePanel.SetActive(true); GetComponent().Play(); } public void OnEatPacdot(GameObject go) { pacdotGos.Remove(go); } public void OnEatSuperPacdot() { Invoke("CreateSuperPacdot", 10f); isSuperPacman = true; FreezeEnemy(); StartCoroutine("RecoverEnemy"); } private void SetGameState(bool state) { pacman.GetComponent().enabled = state; binky.GetComponent().enabled = state; clyde.GetComponent().enabled = state; inky.GetComponent().enabled = state; pinky.GetComponent().enabled = state; }

12.UI逻辑的完善与计分面板的显示

private int pacdotNum = 0; private int nowEat = 0; public int score = 0; //更新显示 private void Update() { if(nowEat == pacdotNum && pacman.GetComponent().enabled != false) { gamePanel.SetActive(false); Instantiate(winPrefab); StopAllCoroutines(); SetGameState(false); } if(nowEat == pacdotNum) { if (Input.anyKeyDown) { SceneManager.LoadScene(0); } } if (gamePanel.activeInHierarchy) { remainText.text = "Remain:\n\n" + (pacdotNum - nowEat); nowText.text = "Eaten:\n\n" + nowEat; remainText.text = "Remain:\n\n" + score; } }

在合适的地方对三个参数进行添加

在GhostMove中完善游戏结束的代码

private void OnTriggerEnter2D(Collider2D collision) { if (collision.gameObject.name == "Pacman") { if (GameManager._instance.isSuperPacman) { transform.position = startPos - new Vector3(0, 3, 0); index = 0; GameManager._instance.score += 500; } else { collision.gameObject.SetActive(false); GameManager._instance.gamePanel.SetActive(false); Instantiate(GameManager._instance.gameoverPrefab); Invoke("ReStart", 3f); } } } private void ReStart() { SceneManager.LoadScene(0); }

运行程序结果如下

13.发布游戏



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3